package com.rc.evcharger.protocol.ylevcharger.service;

import com.alibaba.fastjson.JSON;
import com.github.dozermapper.core.Mapper;
import com.github.pagehelper.util.StringUtil;
import com.rc.evcharger.biz.log.ChargedProcessLogAssemble;
import com.rc.evcharger.biz.notify.NotifyStartChargeResult;
import com.rc.evcharger.biz.notify.NotifyStopChargeResult;
import com.rc.evcharger.biz.notify.NotiyStationsStatus;
import com.rc.evcharger.common.config.MqCommandConfig;
import com.rc.evcharger.common.constant.SocketConstant;
import com.rc.evcharger.common.constant.WebConstant;
import com.rc.evcharger.common.dto.CalcalateResultDto;
import com.rc.evcharger.common.dto.CalculateDto;
import com.rc.evcharger.common.dto.ChargeBalaceDto;
import com.rc.evcharger.common.enums.ChargePhaseEnum;
import com.rc.evcharger.common.enums.yl.YlStartFailEnum;
import com.rc.evcharger.common.enums.yl.YlStopReasonEnum;
import com.rc.evcharger.common.enums.yl.YlWarnCode104Enum;
import com.rc.evcharger.common.mq.MqProducer;
import com.rc.evcharger.common.terminal.ChargeControlResult;
import com.rc.evcharger.common.utils.DataUtil;
import com.rc.evcharger.common.utils.DateHelper;
import com.rc.evcharger.common.utils.ToFrameUtil;
import com.rc.evcharger.model.elec.ElecGun;
import com.rc.evcharger.model.elec.ElecPile;
import com.rc.evcharger.model.elec.ElecStationPrice;
import com.rc.evcharger.model.member.MemberInfo;
import com.rc.evcharger.model.order.OrderComment;
import com.rc.evcharger.model.order.OrderDelayPush;
import com.rc.evcharger.model.order.OrderInfo;
import com.rc.evcharger.model.rc.RcOrderTrace;
import com.rc.evcharger.redis.RedChargeDataService;
import com.rc.evcharger.redis.RedPileService;
import com.rc.evcharger.service.OrderCostService;
import com.rc.evcharger.service.discount.TenantDiscountMemberStationService;
import com.rc.evcharger.service.elec.*;
import com.rc.evcharger.service.handle.ChargeHandler;
import com.rc.evcharger.service.handle.ChargePriceHandler;
import com.rc.evcharger.service.member.MemberInfoService;
import com.rc.evcharger.service.order.OrderCommentService;
import com.rc.evcharger.service.order.OrderDelayPushService;
import com.rc.evcharger.service.order.OrderDetailService;
import com.rc.evcharger.service.order.OrderInfoService;
import com.rc.evcharger.service.rc.RcOrderTraceService;
import com.rc.evcharger.service.rc.RcOrderTraceServiceImpl;
import com.rc.evcharger.service.tenant.TenantSettingService;
import com.rc.evcharger.vo.charge.ChargeBalaceRet;
import com.rc.evcharger.vo.charge.ChargeReportRet;
import com.rc.evcharger.vo.charge.StopChargeReq;
import com.rc.mutievcharger.dto.ylevcharger.terminal.YlTerminalMessage;
import com.rc.mutievcharger.dto.ylevcharger.terminal.req.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.Date;
import java.util.List;

/**
 * Create by Yang on 2019/3/16
 */
@Service
public class YlChargeMessageServiceImpl implements YlChargeMessageService {
    private static Logger logger = LoggerFactory.getLogger(YlChargeMessageServiceImpl.class);

    //最低停止充电金额
    //private final BigDecimal STOP_CHARGING_LIMIT = new BigDecimal("1");
    //private CarVinUtil carVinUtil = CarVinUtil.newInstance();

    @Autowired
    private Mapper dozerMapper;

    @Autowired
    private MqProducer mqProducer;

    @Autowired
    private NotifyStartChargeResult notifyStartChargeResult;

    @Autowired
    private NotifyStopChargeResult notifyStopChargeResult;

    @Autowired
    private NotiyStationsStatus notiyStationsStatus;

    @Autowired
    private ElecPileService elecPileService;

    @Autowired
    private RcOrderTraceService rcOrderTraceService;

    @Autowired
    private ElecPileOfflineService elecPileOfflineService;

    @Autowired
    private ElecGunService elecGunService;

    @Autowired
    private OrderInfoService orderService;

    @Autowired
    private OrderCostService orderCostService;

    @Autowired
    private ElecStationService elecStationService;

    @Autowired
    private RedChargeDataService redChargeDataService;

    @Autowired
    private MemberInfoService memberService;

    @Autowired
    private RedPileService redPileService;

    @Autowired
    private OrderInfoService orderInfoService;

    @Autowired
    private ElecStationPriceService elecStationPriceService;

    @Autowired
    private OrderDetailService orderDetailService;

    @Autowired
    private OrderCommentService orderCommentService;

    @Autowired
    private ChargedProcessLogAssemble chargedProcessLogAssemble;

    @Autowired
    private TenantDiscountMemberStationService tenantDiscountMemberStationService;

    @Autowired
    private OrderDelayPushService orderDelayPushService;

    @Autowired
    private TenantSettingService tenantSettingService;

    @Autowired
    private MqCommandConfig mqCommandConfig;

    @Autowired
    private ChargeHandler chargeHandler;

    @Autowired
    private ChargePriceHandler chargePriceHandler;

    @Autowired
    private ElecPileHostService elecPileHostService;

    @Override
    public void login(ElecGun elecGun, YlTerminalMessage msg) {
        try {
            YlLoginCommondReq loginCommondReq = (YlLoginCommondReq) new YlLoginCommondReq().getResult(msg.getData());
            ElecPile elecPile = elecPileService.selectByPrimaryKey(elecGun.getElecPileId());

            //如果电桩登录之前是离线状态，则保存离线记录
            //桩状态,0: 离网；1: 空闲；2: 占用（未充电）；3: 占用（充电中）；4: 占用（预约锁定）；255: 故障 默认1
            if (elecPile.getStatus().equals(SocketConstant.OFF_LINE)) {
                elecPileOfflineService.addPileOffline(elecPile.getElecPileId(), elecPile.getLogoutTime(), new Date(), Integer.valueOf(SocketConstant.OFF_LINE));
            }

            //更新充电桩状态为在线
            ElecPile newElecPile = new ElecPile();
            newElecPile.setElecPileId(elecPile.getElecPileId());
            newElecPile.setProgramVersion(loginCommondReq.getPileServerVersion().toString());
            newElecPile.setStatus(Integer.valueOf(SocketConstant.ON_LINE));
            newElecPile.setElecOffOnline(String.valueOf(SocketConstant.ON_LINE));   //更新强制状态

            elecPileService.updateByPrimaryKeySelective(newElecPile);

            //推送电桩状态
            notiyStationsStatus.notifyPileStatus(elecPile);
            //更新桩通讯地址
            elecPileHostService.updateHostByElecPileId(elecPile.getElecPileId());

            //更新电桩版本号
//            YlLoginCommondReq result = (YlLoginCommondReq) new YlLoginCommondReq().getResult(msg.getData());
//            elecPileService.updateVersion(elecPile.getElecPileId(), result.getSoftwareversion().toString());
        } catch (Exception e) {
            logger.error("yl.login方法解析出错,对应的电桩ID为:" + elecGun.getPileRuta(), e);
        }
    }

    @Override
    @Transactional
    public void loginOut(ElecGun elecGun) {
        ElecPile elecPile = elecPileService.selectByPrimaryKey(elecGun.getElecPileId());
        //更新充电桩状态为离线
        elecPile.setStatus(Integer.valueOf(SocketConstant.OFF_LINE));
        //记录最后一次登出时间
        elecPile.setLogoutTime(new Date());
        elecPileService.updateByPrimaryKeySelective(elecPile);

        //更新枪为离线状态1
        List<ElecGun> elecGuns = elecGunService.listByElecPileId(elecPile.getElecPileId());
        elecGuns.stream().forEach(elecGun0 -> {
            elecGun0.setStatus(4);
            elecGunService.updateByPrimaryKeySelective(elecGun0);
        });

        //推送电桩状态
        notiyStationsStatus.notifyPileStatus(elecPile);
    }

    @Override
    public void hearBeat(ElecGun pile, YlTerminalMessage msg) {
        //永联心跳包不做处理
    }

    @Override
    public ChargeReportRet chargeReport(ElecGun elecGun, YlTerminalMessage msg) {
        YlChargingCommandReq result = (YlChargingCommandReq) new YlChargingCommandReq().getResult(msg.getData());

        //todo 获取测试电量 每次递增+1  上线前必须完毕！！！
//        crr.setPower(ChargeProcessDataTest.getInstance().getPower());

        String s = YlWarnCode104Enum.getWarnCode104(result.getWarnCode().intValue());

        try {
            ChargeReportRet fcrr = new ChargeReportRet(SocketConstant.STOP_NORMAL_0X0);

            ElecPile elecPile = elecPileService.selectByPrimaryKey(elecGun.getElecPileId());

            //更新桩通讯地址
            elecPileHostService.updateHostByElecPileId(elecGun.getElecPileId());
            String gunStatus = redChargeDataService.getGunStatus(elecPile.getPileRtua(), elecGun.getGunNum());
            //更新充电中状态
            int value = 0;
            if (result.getRunStatus().equals("06")) {//故障？
                elecPileService.updateGunNormal(elecPile.getElecPileId(), elecGun.getGunNum(), 255);
                logger.info("枪编号状态:{},上报故障状态,订单号:{},报文runstatus:{}", elecGun.getGunNo(), s, result.getOrderNum(), result.getRunStatus());
            } else if (("02".equals(result.getConnectStatus()) || "01".equals(result.getConnectStatus())) && !"02".equals(result.getRunStatus())) {
                value = 1;// 插枪中
                logger.info("枪编号状态:{},上报插枪状态,订单号:{},报文runstatus:{}", elecGun.getGunNo(), s, result.getOrderNum(), result.getRunStatus());
                elecPileService.updateGunUsing(elecPile.getElecPileId(), elecGun.getElecGunId(), SocketConstant.GUN_PREPARE);
            } else if ("00".equals(result.getRunStatus())) {
                value = 0;// 空闲中
                elecPileService.updateGunUsing(elecPile.getElecPileId(), elecGun.getElecGunId(), SocketConstant.GUN_LEISURE);
                logger.info("枪编号状态:{},上报空闲状态,订单号:{},报文runstatus:{}", elecGun.getGunNo(), s, result.getOrderNum(), result.getRunStatus());
                //todo 结算模块 插枪变空闲时，结算占用费
                if (gunStatus.equals("1")) {
                    int i = elecStationService.selectOccupyStatusByelecStationId(elecPile.getElecStationId());
                    if (i == 1) {
                        //状态5变更为 4或 6
                        String orderNum = orderCostService.updateOccupyOrderinfoCost(elecPile.getElecPileId(), elecGun.getElecGunId());
                        if (orderNum != null) {
                            notifyStopChargeResult.notifyOrderStop(orderNum, SocketConstant.CON0, SocketConstant.CON0, 0);
                        }
                    }
                }

            } else if ("02".equals(result.getRunStatus())) {//充电中
                value = -1;// 充电中
                elecPileService.updateGunUsing(elecPile.getElecPileId(), elecGun.getElecGunId(), SocketConstant.GUN_USE);
                logger.info("枪编号状态:{},上报充电中状态,订单号:{},报文runstatus:{}", elecGun.getGunNo(), s, result.getOrderNum(), result.getRunStatus());
            }

            redChargeDataService.putGunStatus(elecPile.getPileRtua(), elecGun.getGunNum(), String.valueOf(value));

            //不在充电中将不做处理
            if (value != -1) {
                return fcrr;
            }

            // 获取订单号;
            String orderNum = result.getOrderNum();
            if (StringUtil.isEmpty(orderNum)) {
                return fcrr;
            }
            OrderInfo order = orderService.selectByOrderNum(orderNum);

            //如果订单不存在，则根据上报指令反向生成订单;
            if (order == null) {

                if (orderNum.endsWith("00000") || orderNum.length() == 1) {
                    //不存在订单，将不做处理
                    logger.error("不存在订单，将不做处理，对应桩编号:{},订单号:{}", elecPile.getPileNo(), orderNum);
                    fcrr.setStopType(SocketConstant.STOP_NORMAL_0X0);
                    return fcrr;
                }
                //先生成
                orderService.addOrder(elecPile.getPileRtua(), result.getGunNum(), orderNum);

                //再查找
                order = orderService.selectByOrderNum(orderNum);

                //广播启动成功的消息
                notifyStartChargeResult.notifyOrderStart(orderNum, SocketConstant.CON0);

            }

            if (order != null && "2".equals(order.getStatus())) {
                logger.info("订单已结算，将不会重复处理，对应订单号:{},桩编号:{},枪号:{}", order.getOrderNum(), elecPile.getPileNo(), elecGun.getGunNum());
                return fcrr;
            }

            //如果订单不存在，则根据上报指令反向生成订单;
            if (order == null) {

                OrderComment orderComment = orderCommentService.selectByGunId(elecGun.getElecGunId());

                //先生成
                orderService.addOrder(elecPile.getPileRtua(), result.getGunNum(), orderComment.getOrderNum());

                //再查找
                order = orderService.selectByOrderNum(orderComment.getOrderNum());

                //广播启动成功的消息
                notifyStartChargeResult.notifyOrderStart(orderComment.getOrderNum(), SocketConstant.CON0);

            }

            //防止被平台停止的订单再产生数据，从而引起负数问题
            if ("25".contains(order.getStatus())) {
                //平台停止
                fcrr.setStopType(SocketConstant.STOP_IS_ORDER_0XD);
                return fcrr;
            }


            MemberInfo memberInfo = memberService.selectByPrimaryKey(order.getMemberId());
            fcrr.setOrderNum(order.getOrderNum());
            fcrr.setGunNum(result.getGunNum());
            fcrr.setMemberId(memberInfo.getMemberId());

            //更新启动成功
            //redChargeDataService.putChargeResult(pile.getPileRtua(), "1", memberInfo.getMobile(), 2);
            redChargeDataService.putChargeResult(elecPile.getPileRtua(), "1", order.getOrderNum(), 2);

            //添加充电的开始soc，添加订单的vin码
            orderService.updateOrderBySocOrVin(order.getOrderId(), result.getSoc(), WebConstant.INVALID_VIN);

            //ChargeReportResult转换为ChargeBalaceDto
            ChargeBalaceDto cbdto = dozerMapper.map(result, ChargeBalaceDto.class);

            //保存到ycc中的hash值中
            redPileService.putPileToRedis(elecPile.getPileRtua(), cbdto);
            // 获取当前时间并存入redis中;
            redChargeDataService.putChargeReportTime(elecPile.getPileRtua(), result.getGunNum(), order.getOrderNum(), DateHelper.dataToString(new Date(), DateHelper.DATE_COMMON_FORMAT));
            // 获取电压并存入redis中;
            redChargeDataService.putVol(elecPile.getPileRtua(), result.getGunNum(), order.getOrderNum(), result.getVoltage());
            // 获取电流并存入redis中;
            redChargeDataService.putElec(elecPile.getPileRtua(), result.getGunNum(), order.getOrderNum(), result.getElec());
            // 保存bms需求电流;
            redChargeDataService.putDemandElec(elecPile.getPileRtua(), result.getGunNum(), order.getOrderNum(), result.getDemandElec());
            // 保存bms需求电流;
            redChargeDataService.putDemandVoltage(elecPile.getPileRtua(), result.getGunNum(), order.getOrderNum(), result.getDemandVoltage());
            // 获取soc并存入redis中;
            redChargeDataService.putSoc(elecPile.getPileRtua(), result.getGunNum(), order.getOrderNum(), result.getSoc());
            //获取充电时长并存入redis中;
            redChargeDataService.putRemainChargingTime(elecPile.getPileRtua(), result.getGunNum(), order.getOrderNum(), result.getRemainChargingTime());
            //获取电枪温度 偏移量 -50
            result.setTemperatureGun(result.getTemperatureGun().subtract(new BigDecimal("50")));
            redChargeDataService.putTemperatureHigh(elecPile.getPileRtua(), result.getGunNum(), order.getOrderNum(), result.getTemperatureGun());
            //保存订单开始时间的电价列表，每次都查缓存数据，不受数据库电价改动影响
            chargePriceHandler.putRedPricesHandler(elecPile.getPileRtua(), result.getGunNum(), order.getOrderNum(), elecPile.getElecStationId());
            //轨迹入库
//            rcOrderTraceService.insertByChargeReport(order, result.getPower(), result.getSoc(), pile.getPileNo());
            //获取电价
            ElecStationPrice elecStationPrice = elecStationPriceService.selectRedValidElecStationPriceByDate(elecPile.getPileRtua(), result.getGunNum(), order.getOrderNum(), new Date());
            if (elecStationPrice == null) {
                //电价异常停止
                fcrr.setStopType(SocketConstant.STOP_ELEC_PRICE_EXCEPTION_0x5);
                return fcrr;
            }

            //todo 实时计算原价电量金额
            CalculateDto calculateDto = new CalculateDto();
            calculateDto.setElecPileId(elecPile.getElecPileId());
            calculateDto.setGunNum(result.getGunNum());
            calculateDto.setPileRtua(elecPile.getPileRtua());
            calculateDto.setElecStationPriceId(elecStationPrice.getPriceId());
            calculateDto.setMobile(memberInfo.getMobile());
            calculateDto.setPower(result.getPower());
            calculateDto.setOrderNum(order.getOrderNum());
            //添加实时电价
            calculateDto.setServicePrice(elecStationPrice.getServicePrice());
            calculateDto.setElecPrice(elecStationPrice.getElecPrice());

            CalcalateResultDto calcalateResultDto = chargeHandler.calculateAmount(calculateDto);


            /**获取个人或者企业余额**/
            BigDecimal account = memberService.getAccountByChargeType(order.getOrderId());
            BigDecimal subAcount = account.subtract(calcalateResultDto.getTotalAmount());

            logger.info(this.getClass().getSimpleName() + " A5订单号:{},soc:{},电量:{},电流:{},电压:{},会员余额:{},基本电费:{},服务费:{},总金额:{}，剩余时长:{},枪温:{}",
                    order.getOrderNum(), result.getSoc(), result.getPower(), result.getElec(), result.getVoltage(), account,
                    calcalateResultDto.getElecAmount(), calcalateResultDto.getServiceAmount(), calcalateResultDto.getTotalAmount(), result.getRemainChargingTime(), result.getTemperatureGun());


            /**如果用户余额不足,后台自动结算**/
            BigDecimal stop_charge_account_limit = tenantSettingService.query_stop_charge_account_limit(memberInfo.getTenantCode());
            if (subAcount.compareTo(stop_charge_account_limit) == -1) {
                logger.warn("如果用户余额不足,后台自动结算,:{},:{},:{}", memberInfo.getMemberId(), order.getOrderNum(), stop_charge_account_limit);

                //余额不足停止
                fcrr.setStopType(SocketConstant.STOP_BALANCE_LOW_0x6);
                return fcrr;
            }

            //获取分时段差异电价
            ElecStationPrice bsp = chargePriceHandler.lastPriceHandler(calculateDto, elecStationPrice);
            if (bsp != null) {

                //按上次的实时充电量进行分段入库
                cbdto.setPower(calcalateResultDto.getLastPower()); //获取上一次充电轨迹的电量
                orderDetailService.saveByCharging(order.getOrderId(), cbdto, bsp, calcalateResultDto.getLastElecAmount(), calcalateResultDto.getLastTotalAmount());
                //redChargeDataService.putEpgPriceId(pile.getPileRtua(), crr.getGunNum(), order.getOrderNum(), elecStationPrice.getPriceId());
                String jsonString = JSON.toJSONString(elecStationPrice);
                redChargeDataService.putOrderInfoCurrentPrice(elecPile.getPileRtua(), result.getGunNum(), order.getOrderNum(), jsonString);
            }

            //异步保存充电过程
            chargedProcessLogAssemble.assembleChargedProcessLog(ChargePhaseEnum.ON_CHARGEING, result, order, calcalateResultDto.getElecAmount(), calcalateResultDto.getServiceAmount());

            return fcrr;
        } catch (Exception e) {
            logger.error("YL.A5报文解析异常", e);
            return new ChargeReportRet(SocketConstant.CON0);
        }

    }

    /**
     * 充电桩启动响应
     *
     * @param gun
     * @param msg
     * @return
     */
    @Override
    public ChargeReportRet start(ElecGun gun, YlTerminalMessage msg) {

        YlStartCommandReq startCommandReq = (YlStartCommandReq) new YlStartCommandReq().getResult(msg.getData());

        //0.发送指令成功  1.发送指令失败   2.启动成功    3.启动失败  4.停止成功  5.停止失败
        int chargeResult = SocketConstant.CON2;  //启动成功

        ElecPile pile = elecPileService.selectByPrimaryKey(gun.getElecPileId());

        OrderComment orderComment = orderCommentService.selectByGunId(gun.getElecGunId());
        //启动结果
        String startResult = YlStartFailEnum.getYlStartFailEnumMsg(startCommandReq.getResult().intValue());
        startResult = startResult + " " + YlStopReasonEnum.getStopReasonMsg(startCommandReq.getResult().intValue());
        logger.warn("充电指令结果数据：桩地址:{},枪号:{},结果:{}", pile.getPileRtua(), startCommandReq.getGunNum(), startResult);

        //启动成功
        if (SocketConstant.STR_CON0.equals(startCommandReq.getResult().toString())) {
            logger.warn("YL可启动状态，结果数据：桩地址:{},枪号:{},结果:{}", pile.getPileRtua(), startCommandReq.getGunNum(), startResult);
        } else {
            // 将电桩对应的枪口变回可用状态
            elecPileService.updateGunUsing(pile.getElecPileId(), gun.getElecGunId(), SocketConstant.GUN_LEISURE);

            chargeResult = SocketConstant.CON3;    //启动失败

            logger.error("YL启动失败数据：桩地址:{},枪号:{},结果:{}", pile.getPileRtua(), startCommandReq.getGunNum(), startResult);

            //广播启动失败的消息
//            notifyStartChargeResult.notifyOrderStart(orderComment.getOrderNum(), SocketConstant.CON1);
        }

        //删除枪约束
        redChargeDataService.removeCheckPileTime(pile.getPileRtua(), gun.getGunNum(), "");

        //更新失败原因
        redChargeDataService.putChargeResult(pile.getPileRtua(), gun.getGunNum(), orderComment.getOrderNum(), chargeResult);

        //保存充电过程
//        chargedProcessLogAssemble.assembleChargedProcessLog(startCommandReq, orderComment);

        return new ChargeReportRet(0);
    }

    @Override
    public ChargeReportRet stop(ElecGun elecGun, YlTerminalMessage msg) {

        YlStopCommandReq stopCommandReq = (YlStopCommandReq) new YlStopCommandReq().getResult(msg.getData());

        //获取充电中订单信息
        ElecPile pile = elecPileService.selectByPrimaryKey(elecGun.getElecPileId());
        OrderInfo orderInfo = orderInfoService.selectByPileIdAndGunId(pile.getElecPileId(), elecGun.getElecGunId());
        MemberInfo memberInfo = memberService.selectByPrimaryKey(orderInfo.getMemberId());

        Integer chargeResult = SocketConstant.CON4;

        if ("00".equals(stopCommandReq.getCmdResult())) {

            logger.warn("stop()停止成功,订单号：{}" + orderInfo.getOrderNum());

            //0.发送指令成功  1.发送指令失败   2.启动成功    3.启动失败  4.停止成功  5.停止失败
            //redChargeDataService.putChargeResult(pile.getPileRtua(), elecGun.getGunNum(),
            //        memberInfo.getMobile(), chargeResult);
            redChargeDataService.putChargeResult(pile.getPileRtua(), elecGun.getGunNum(),
                    orderInfo.getOrderNum(), chargeResult);
        } else {

            chargeResult = SocketConstant.CON5;

            logger.error("stop()停止失败！订单号:{},失败原因:{}" + orderInfo.getOrderNum(), stopCommandReq.getCmdCount());

            //0.发送指令成功  1.发送指令失败   2.启动成功    3.启动失败  4.停止成功  5.停止失败
            //redChargeDataService.putChargeResult(pile.getPileRtua(), stopCommandReq.getGunNum(),
            //        memberInfo.getMobile(), chargeResult);
            redChargeDataService.putChargeResult(pile.getPileRtua(), stopCommandReq.getGunNum(),
                    orderInfo.getOrderNum(), chargeResult);


            StopChargeReq stopChargeReq = new StopChargeReq();
            stopChargeReq.setElecPileId(pile.getElecPileId());
            stopChargeReq.setOrderNum(orderInfo.getOrderNum());
            stopChargeReq.setGunNum(elecGun.getGunNum());
            stopChargeReq.setMemberId(memberInfo.getMemberId());
            stopChargeReq.setStopType(SocketConstant.STOP_NORMAL_0X0);

            String msg0 = JSON.toJSONString(stopChargeReq);
            mqProducer.sendDelay(mqCommandConfig.getCONTROLL_8E_DELAY_STOP(), msg0, 1000);
        }


        return null;
    }

    @Override
    public ChargeBalaceRet chargeBalace(ElecGun elecGun, YlTerminalMessage msg) {

        YlTransactionsCommandReq tcr = (YlTransactionsCommandReq) new YlTransactionsCommandReq().getResult(msg.getData());
        try {
            logger.warn("YL收到A6指令做结算处理orderNum:{} ", tcr.getOrderNum());
            OrderInfo order = orderService.selectByOrderNum(tcr.getOrderNum());

            if (order == null) {
                logger.error("YL收到A6异常指令，异常orderNum:{}", tcr.getOrderNum());
                return new ChargeBalaceRet();
            }
            //接收补推的订单
            if ("2".equals(order.getStatus())) {
                //接收补推的结算数据
                OrderDelayPush orderDelayPush = orderDelayPushService.selectOrderNum(tcr.getOrderNum());
                if (orderDelayPush == null) {
                    //ChargeReportResult转换为ChargeBalaceDto
                    ChargeBalaceDto cbdto = dozerMapper.map(tcr, ChargeBalaceDto.class);
                    orderDelayPushService.addOrderDelayPush(cbdto, elecGun.getElecPileId(), order.getOrderId());
                }
                return new ChargeBalaceRet();

            }

            ElecPile pile = elecPileService.selectByPrimaryKey(elecGun.getElecPileId());
            tcr.setGunNum("0" + elecGun.getGunNum());

            MemberInfo memberInfo = memberService.selectByPrimaryKey(order.getMemberId());
            redChargeDataService.putChargeReportTime(pile.getPileRtua(), tcr.getGunNum(), order.getOrderNum(), DateHelper.dataToString(new Date(), DateHelper.DATE_COMMON_FORMAT));
            //soc
            redChargeDataService.putSoc(pile.getPileRtua(), tcr.getGunNum(), order.getOrderNum(), tcr.getEndSoc());
            //获取桩停止原因并存入redis中
            redChargeDataService.putPileStopMode(pile.getPileRtua(), tcr.getGunNum(), order.getOrderNum(), tcr.getEndReason().intValue());
            //保存订单开始时间的电价列表，每次都查缓存数据，不受数据库电价改动影响
            chargePriceHandler.putRedPricesHandler(pile.getPileRtua(), tcr.getGunNum(), order.getOrderNum(), pile.getElecStationId());
            //获取电价
            ElecStationPrice elecStationPrice = elecStationPriceService.selectRedValidElecStationPriceByDate(pile.getPileRtua(), tcr.getGunNum(), order.getOrderNum(), new Date());
            if (elecStationPrice == null) {
                // 订单结算 默认停止原因为手动停止;
                orderCostService.updateOrderCost(order.getOrderNum(), SocketConstant.STOP_NORMAL_0X0);
                ///推送订单停止状态
                notifyStopChargeResult.notifyOrderStop(order.getOrderNum(), SocketConstant.CON0, SocketConstant.CON0, 0);

                logger.error("YL收到A6,该时段没有对应电价错误,无法计算电价！！！桩：{},订单号:{}" + pile.getPileRtua(), order.getOrderNum());
                return new ChargeBalaceRet(WebConstant.CON1 + "", order.getOrderId());
            }

            //todo 实时计算原价电量金额
            CalculateDto calculateDto = new CalculateDto();
            calculateDto.setElecPileId(pile.getElecPileId());
            calculateDto.setPileRtua(pile.getPileRtua());
            calculateDto.setGunNum(elecGun.getGunNum());
            calculateDto.setElecStationPriceId(elecStationPrice.getPriceId());
            calculateDto.setMobile(memberInfo.getMobile());
            calculateDto.setPower(tcr.getPower());
            calculateDto.setOrderNum(order.getOrderNum());
            //添加实时电价
            calculateDto.setServicePrice(elecStationPrice.getServicePrice());
            calculateDto.setElecPrice(elecStationPrice.getElecPrice());

            CalcalateResultDto calcalateResultDto = chargeHandler.calculateAmount(calculateDto);

            //停止方式
            String elecPileStopReasonResult = YlStopReasonEnum.getStopReasonMsg(tcr.getEndReason().intValue());
            logger.info(this.getClass().getSimpleName() + "A6订单号:{},电量:{},余额:{},停止原因:{}", order.getOrderNum(), tcr.getPower(),
                    memberInfo.getJoinMemberAccount().getAccount(), elecPileStopReasonResult);

            // 订单结算 默认停止原因为手动停止;
            orderCostService.updateOrderCost(order.getOrderNum(), SocketConstant.STOP_NORMAL_0X0);
            //推送订单停止状态
            notifyStopChargeResult.notifyOrderStop(order.getOrderNum(), SocketConstant.CON0, SocketConstant.CON0, 0);
            //chargedProcessLogAssemble.assembleChargedProcessLog(ChargePhaseEnum.SETTLED, tcr, order, basePriceValueAll, servicePriceValueAll);

            return new ChargeBalaceRet(WebConstant.CON1 + "", order.getOrderId());
        } catch (Exception e) {
            logger.error("YL.收到A6指令做结算处理异常", e);
            return new ChargeBalaceRet();
        }
    }

    public static void main(String[] args) {
        //充电策略0:充满为止 1:时间控制充电 2:金额控制充电 3:电量控制充电
        //启动策略参数 充电策略参数 时间单位为 1 秒 金额单位为 0.01 元  电量时单位为 0.01kw
        String a = "2";
        String value = "360";
        switch (a) {
            case "1":
                System.out.println("01 00 00 00");
                System.out.println(DataUtil.getValuetoHex(new BigDecimal(value), 0));
                break;
            case "2":
                System.out.println("02 00 00 00");
                //扩大100倍
                System.out.println(DataUtil.getValuetoHex(new BigDecimal(value), 2));
                break;
            default:
                System.out.println("00 00 00 00");
                System.out.println("00 00 00 00");
        }
    }
}
